package cn.edu.neu.vmmigeval;

import cn.edu.neu.vmmigeval.cloud.config.CloudletRegistry;
import cn.edu.neu.vmmigeval.cloud.config.HostRegistry;
import cn.edu.neu.vmmigeval.cloud.config.VmRegistry;
import cn.edu.neu.vmmigeval.cloud.entity.*;
import cn.edu.neu.vmmigeval.cloud.policy.CloudletScheduler;
import cn.edu.neu.vmmigeval.cloud.policy.VmScheduler;
import cn.edu.neu.vmmigeval.cloud.util.DatacenterUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by yfwz100 on 16/2/25.
 */
public class InitDatacenter {

	/*public static int hostId = 0 ;
    public static int vmId = 0 ;*/

    public int hostId = 0;
    public int vmId = 0;

    public DataCenter initDatacenter(Map<HostRegistry, Integer> hostsMaps) {

        DataCenter datacenter = new DataCenter();
        // int hostId = 0 ;

        List<Host> hosts = new ArrayList<Host>();
        for (Map.Entry<HostRegistry, Integer> entry : hostsMaps.entrySet()) {

            int size = entry.getValue();
            int flag = 0;
            while (flag < size) {

                HostRegistry hr = entry.getKey();
                Host host = new Host(hostId, hr.getPeList(), hr.getTotalCpu(),
                        hr.getTotalRam(), hr.getTotalBw(), hr.getTotalDisk(), new VmScheduler() {
                });
                hosts.add(host);
                hostId++;
                flag++;
            }
        }
        datacenter.setHosts(hosts);

        return datacenter;
    }


    public DataCenterBroker initDatacenterBrokerVms(DataCenter datacenter, Map<VmRegistry, Integer> vmsMaps, String guimo) {

        DataCenterBroker broker = new DataCenterBroker();

        List<Vm> vms = new ArrayList<Vm>();

        Map<Integer, List<Integer>> maps = DatacenterUtil.getTotalMap(guimo);
        // int vmId = 0;
        for (Map.Entry<VmRegistry, Integer> entry : vmsMaps.entrySet()) {

            int size = entry.getValue();
            int flag = 0;
            while (flag < size) {

                VmRegistry vr = entry.getKey();
                Vm vm = new Vm(vmId, vr.getMips(), vr.getRam(), vr.getBw(), vr.getDisk(), new CloudletScheduler());

                /**
                 * 该方法完成le
                 */

                int hostId = DatacenterUtil.getHostForVm(vm, maps);
                Host host = datacenter.getHosts().get(hostId);
                host.getVmList().add(vm);
                vm.setHost(host);
                vms.add(vm);

				/*
                 boolean allocationSuccess = datacenter.getVmAllocation().allocateHostForVm(datacenter.getHosts(),vm);
				 if(allocationSuccess){
					 vms.add(vm);
				 }else{
					 System.out.println("^^^^^^给host 分配虚拟机   "+vm.getId()+" 失败");
				 }*/


                vmId++;
                flag++;
            }
        }
        broker.setVms(vms);
        return broker;
    }

    public int initDatacenterBrokerCloudlets(DataCenterBroker broker, Map<CloudletRegistry, Integer> cloudletMaps, int clock) {
        List<Cloudlet> cloudlets = new ArrayList<Cloudlet>();
        int cloudletId = 0;
        for (Map.Entry<CloudletRegistry, Integer> entry : cloudletMaps.entrySet()) {

            int size = entry.getValue();
            int flag = 0;
            while (flag < size) {

                CloudletRegistry clr = entry.getKey();
                Cloudlet cloudlet = new Cloudlet(cloudletId, clr.getCloudletLength(), clock,
                        clr.getCpuUtilizationModel(), clr.getRamUtilizationModel(), clr.getBwUtilizationModel(), clr.getDiskUtilizationModel());

                /**
                 * 该方法还没有完成
                 */

                broker.getCloudletAllocation().allocateVmForCloudlet(broker.getVms(), cloudlet);
                cloudlets.add(cloudlet);
                cloudletId++;
                flag++;

            }
        }
        broker.setCloudlets(cloudlets);
        return cloudletId;
    }

    public static int addCloudlets(int cloudletIds, DataCenterBroker broker, CloudletRegistry myclr, int clock, String guimo) {


        Map<CloudletRegistry, Integer> cloudletMaps = new HashMap<CloudletRegistry, Integer>();

        // MS
        if (guimo.equals("big")) {
            cloudletMaps.put(myclr, 1000);
        }
        // 规模为1200的时候执行这个
        if (guimo.equals("middle")) {
            cloudletMaps.put(myclr, 360);
        }
        // 规模为600的时候执行这个
        int num = (int) (Math.random() * 7500);

        if (guimo.equals("small")) {
            cloudletMaps.put(myclr, 180);//180   /1600
        }

        List<Cloudlet> cloudlets = new ArrayList<Cloudlet>();
        int cloudletId = cloudletIds;
        for (Map.Entry<CloudletRegistry, Integer> entry : cloudletMaps.entrySet()) {

            int size = entry.getValue();
            int flag = 0;
            while (flag < size) {

                CloudletRegistry clr = entry.getKey();
                Cloudlet cloudlet = new Cloudlet(cloudletId, clr.getCloudletLength(), clock,
                        clr.getCpuUtilizationModel(), clr.getRamUtilizationModel(), clr.getBwUtilizationModel(), clr.getDiskUtilizationModel());

                /**
                 * 该方法还没有完成
                 */

                boolean result = broker.getCloudletAllocation().allocateVmForCloudlet(broker.getVms(), cloudlet);
                try {
                    if (!result) {
                        throw new Exception("++任务无法分配到虚拟机");
                    }/*else{
						 System.out.println("已经为云任务分配到虚拟机！");
					 }*/
                } catch (Exception e) {
                    e.printStackTrace();
                }
                cloudlets.add(cloudlet);
                cloudletId++;
                flag++;

            }
        }
        broker.getCloudlets().addAll(cloudlets);
        return cloudletId;

    }


}
